package com.caltco.cargo.ops.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.caltco.cargo.ops.auth.bo.AdminUserDetails;
import com.caltco.cargo.ops.common.base.gen.BaseServiceImpl;
import com.caltco.cargo.ops.modules.sys.dao.DailyStatisticsDao;
import com.caltco.cargo.ops.modules.sys.entity.DailyStatistics;
import com.caltco.cargo.ops.modules.sys.entity.LearnWord;
import com.caltco.cargo.ops.modules.sys.entity.SysUserEntity;
import com.caltco.cargo.ops.modules.sys.request.StatisticsTimeRequest;
import com.caltco.cargo.ops.modules.sys.service.DailyStatisticsService;
import com.caltco.cargo.ops.modules.sys.vo.DailyStatisticsByModelVO;
import com.caltco.cargo.ops.modules.sys.vo.DailyStatisticsVO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.List;

@Service
public class DailyStatisticsServiceImp extends BaseServiceImpl<DailyStatisticsDao, DailyStatistics> implements DailyStatisticsService {
    private final DailyStatisticsDao dailyStatisticsDao;

    public DailyStatisticsServiceImp(DailyStatisticsDao dailyStatisticsDao) {
        this.dailyStatisticsDao = dailyStatisticsDao;
    }

    public Long getUserIdByToken() {
        return ((AdminUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUserEntity().getUserId();
    }
    public Date getStartOfWeek() {
        LocalDate startOfWeek = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        return Date.valueOf(startOfWeek); // 转换成 java.sql.Date
    }

    public Date getEndOfWeek() {
        LocalDate endOfWeek = LocalDate.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        return Date.valueOf(endOfWeek); // 转换成 java.sql.Date
    }

    public Date getToday() {
        return Date.valueOf(LocalDate.now());  // 获取当天日期（YYYY-MM-DD）
    }

    public Date getYesterday() {
        return Date.valueOf(LocalDate.now().minusDays(1));  // 获取昨天的日期（YYYY-MM-DD）
    }

    @Override
    public List<DailyStatisticsVO> getDailyStatistics() {
        List<DailyStatisticsVO> dailyStatisticsVOS = dailyStatisticsDao.selectJoinList(DailyStatisticsVO.class,
                new MPJLambdaWrapper<DailyStatistics>()
                        .selectAll(DailyStatistics.class)
                        .selectAs("SUM(CASE WHEN lw.is_current = 0 THEN 1 ELSE 0 END)", DailyStatisticsVO::getCurrentWord) // 统计正确单词
                        .selectAs("SUM(CASE WHEN lw.is_current = 1 THEN 1 ELSE 0 END)", DailyStatisticsVO::getErrorWord) // 统计错误单词
                        .leftJoin(SysUserEntity.class, SysUserEntity::getId, DailyStatistics::getUserId)
                        .leftJoin(LearnWord.class, "lw", LearnWord::getUserId, SysUserEntity::getId)
                        .eq(LearnWord::getDate, DailyStatistics::getDate)
                        .eq(SysUserEntity::getId, getUserIdByToken())
                        .between(LearnWord::getDate, getStartOfWeek(), getEndOfWeek())
                        .between(DailyStatistics::getDate, getStartOfWeek(), getEndOfWeek())
                        .groupBy(
                                DailyStatistics::getId,
                                DailyStatistics::getUserId,
                                DailyStatistics::getDate,
                                DailyStatistics::getType,
                                DailyStatistics::getCreateAt,
                                DailyStatistics::getCreateName,
                                DailyStatistics::getUpdateName,
                                DailyStatistics::getCreateId,
                                DailyStatistics::getUserId,
                                DailyStatistics::getStudyTime,
                                DailyStatistics::getIsDelete
                        ) // ✅ 添加所有非聚合字段
        );
        return dailyStatisticsVOS;
    }

    @Override
    public DailyStatisticsVO getDailyStatisticsByDay() {
        DailyStatisticsVO dailyStatisticsVO = dailyStatisticsDao.selectJoinOne(DailyStatisticsVO.class,
                new MPJLambdaWrapper<DailyStatistics>()
                        .selectAll(DailyStatistics.class)
                        .selectAs("SUM(CASE WHEN lw.is_current = 0 THEN 1 ELSE 0 END)", DailyStatisticsVO::getCurrentWord) // 统计正确单词
                        .selectAs("SUM(CASE WHEN lw.is_current = 1 THEN 1 ELSE 0 END)", DailyStatisticsVO::getErrorWord) // 统计错误单词
                        .leftJoin(SysUserEntity.class, SysUserEntity::getId, DailyStatistics::getUserId)
                        .leftJoin(LearnWord.class, "lw", LearnWord::getUserId, SysUserEntity::getId)
                        .eq(SysUserEntity::getId, getUserIdByToken())
                        .eq(LearnWord::getDate, getToday())
                        .eq(DailyStatistics::getDate, getToday())
                        .groupBy(
                                DailyStatistics::getId,
                                DailyStatistics::getUserId,
                                DailyStatistics::getDate,
                                DailyStatistics::getType,
                                DailyStatistics::getCreateAt,
                                DailyStatistics::getCreateName,
                                DailyStatistics::getUpdateName,
                                DailyStatistics::getCreateId,
                                DailyStatistics::getUserId,
                                DailyStatistics::getStudyTime,
                                DailyStatistics::getIsDelete
                        ) // ✅ 添加所有非聚合字段
        );
        return dailyStatisticsVO;
    }

    @Override
    public DailyStatisticsVO getDailyStatisticsByYesterday() {
        DailyStatisticsVO dailyStatisticsVO = dailyStatisticsDao.selectJoinOne(DailyStatisticsVO.class,
                new MPJLambdaWrapper<DailyStatistics>()
                        .selectAll(DailyStatistics.class)
                        .selectAs("SUM(CASE WHEN lw.is_current= 0 THEN 1 ELSE 0 END)", DailyStatisticsVO::getCurrentWord) // 统计正确单词
                        .selectAs("SUM(CASE WHEN lw.is_current = 1 THEN 1 ELSE 0 END)", DailyStatisticsVO::getErrorWord) // 统计错误单词
                        .leftJoin(SysUserEntity.class, SysUserEntity::getId, DailyStatistics::getUserId)
                        .leftJoin(LearnWord.class, "lw", LearnWord::getUserId, SysUserEntity::getId)
                        .eq(SysUserEntity::getId, getUserIdByToken())
                        .eq(LearnWord::getDate, getYesterday())
                        .eq(DailyStatistics::getDate, getYesterday())
                        .groupBy(
                                DailyStatistics::getId,
                                DailyStatistics::getUserId,
                                DailyStatistics::getDate,
                                DailyStatistics::getType,
                                DailyStatistics::getCreateAt,
                                DailyStatistics::getCreateName,
                                DailyStatistics::getUpdateName,
                                DailyStatistics::getCreateId,
                                DailyStatistics::getUserId,
                                DailyStatistics::getStudyTime,
                                DailyStatistics::getIsDelete
                        ) // ✅ 添加所有非聚合字段
        );
        return dailyStatisticsVO;
    }

    @Override
    public DailyStatisticsByModelVO DailyStatisticsByModelVO(Integer model) {
        DailyStatisticsByModelVO dailyStatisticsVO = dailyStatisticsDao.selectJoinOne(DailyStatisticsByModelVO.class,
                new MPJLambdaWrapper<DailyStatistics>()
                        .selectAll(DailyStatistics.class)
                        .selectAs("SUM(CASE WHEN lw.is_current = 0 THEN 1 ELSE 0 END)", DailyStatisticsByModelVO::getCurrentWord) // 统计正确单词
                        .selectAs("SUM(CASE WHEN lw.is_current = 1 THEN 1 ELSE 0 END)", DailyStatisticsByModelVO::getErrorWord) // 统计错误单词
                        .leftJoin(SysUserEntity.class, SysUserEntity::getId, DailyStatistics::getUserId)
                        .leftJoin(LearnWord.class, "lw", LearnWord::getUserId, SysUserEntity::getId)
                        .eq(SysUserEntity::getId, getUserIdByToken())
                        .eq(LearnWord::getDate, getToday())
                        .eq(LearnWord::getModel, model)
                        .eq(DailyStatistics::getDate, getToday())
                        .groupBy(
                                DailyStatistics::getId,
                                DailyStatistics::getUserId,
                                DailyStatistics::getDate,
                                DailyStatistics::getType,
                                DailyStatistics::getCreateAt,
                                DailyStatistics::getCreateName,
                                DailyStatistics::getUpdateName,
                                DailyStatistics::getCreateId,
                                DailyStatistics::getUserId,
                                DailyStatistics::getStudyTime,
                                DailyStatistics::getIsDelete) // ✅ 添加所有非聚合字段
        );
        return dailyStatisticsVO;
    }

    @Override
    public Boolean statisticsTime(StatisticsTimeRequest request) {
        Long userId = getUserIdByToken();
        DailyStatistics dailyStatistics = dailyStatisticsDao.selectOne(new LambdaQueryWrapper<DailyStatistics>()
                .eq(DailyStatistics::getUserId, userId)
                .eq(DailyStatistics::getDate, getToday())
                .eq(DailyStatistics::getType, request.getType()));
        if (dailyStatistics != null){
            dailyStatistics.setStudyTime(dailyStatistics.getStudyTime() + request.getLearnTime());
            dailyStatisticsDao.updateById(dailyStatistics);
        }else {
            dailyStatistics = new DailyStatistics();
            dailyStatistics.setStudyTime(request.getLearnTime());
            dailyStatistics.setUserId(userId);
            dailyStatistics.setType(request.getType());
            dailyStatistics.setDate(getToday());
            dailyStatisticsDao.insert(dailyStatistics);
        }
        return true;
    }
}
